#include "CircleWidget.h"
#include <QFont>

CircleWidget::CircleWidget(QWidget *parent)
    : QWidget(parent), dragging(false), angle(0.0)
{
    // 初始化半径长度
    radius = 100.0;
}

CircleWidget::~CircleWidget()
{
}

void CircleWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    // 设置新的坐标原点，比如距离窗口底部和左边各偏移 50 像素
    int originX = 50;
    int originY = height() - 50;

    // 使用 translate() 使得新原点位于偏移后的位置
    painter.translate(originX, originY);
    painter.scale(1, -1);  // 反转Y轴，使其从底部往上增长

    // 设置圆心在坐标系的某个位置，确保在第一象限
    center = QPointF(150, 150);  // 自定义一个位置，确保在第一象限

    // 绘制坐标轴（X轴从左向右，Y轴从下向上）
    painter.setPen(QPen(Qt::black, 2));

    // 绘制X轴
    painter.drawLine(0, 0, width() - originX, 0);  // X轴
    drawArrow(painter, width() - originX, 0, true); // X轴箭头

    // 绘制Y轴
    painter.drawLine(0, 0, 0, height() - originY); // Y轴
    drawArrow(painter, 0, height() - originY, false); // Y轴箭头

    // 添加X轴和Y轴的文字标记
    QFont font = painter.font();
    font.setPointSize(10);
    painter.setFont(font);
    painter.drawText(width() - originX - 25, -15, "X"); // X轴标记稍微远离箭头
    painter.drawText(-15, height() - originY + 25, "Y"); // Y轴标记稍微远离箭头

    // 绘制圆
    painter.setPen(QPen(Qt::blue, 2));
    painter.drawEllipse(center, radius, radius);

    // 计算半径终点
    QPointF endPoint = QPointF(center.x() + radius * qCos(angle),
                               center.y() + radius * qSin(angle)); // 使用正的Y值

    // 绘制半径
    painter.setPen(QPen(Qt::red, 2));
    painter.drawLine(center, endPoint);
}

void CircleWidget::drawArrow(QPainter &painter, int x, int y, bool isXAxis)
{
    QPen pen(Qt::black, 2);
    painter.setPen(pen);

    int arrowSize = 10;
    QPointF p1, p2, p3;

    if (isXAxis) {
        // X轴箭头 (水平向右)
        p1 = QPointF(x, y);
        p2 = QPointF(x - arrowSize, y + arrowSize / 2);
        p3 = QPointF(x - arrowSize, y - arrowSize / 2);
    } else {
        // Y轴箭头 (垂直向上)
        p1 = QPointF(x, y);
        p2 = QPointF(x - arrowSize / 2, y - arrowSize);
        p3 = QPointF(x + arrowSize / 2, y - arrowSize);
    }

    QPolygonF arrowHead;
    arrowHead << p1 << p2 << p3;

    painter.drawPolygon(arrowHead);
}

void CircleWidget::mousePressEvent(QMouseEvent *event)
{
    QPointF mousePos = event->pos();
    mousePos.setY(height() - mousePos.y() - 50);  // 修正鼠标Y坐标，适应新的坐标系
    mousePos.setX(mousePos.x() - 50); // 修正鼠标X坐标
    if (isNearRadius(mousePos)) {
        dragging = true;
    }
}

void CircleWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (dragging) {
        QPointF mousePos = event->pos();

        // 将鼠标的Y坐标适配新的坐标系
        mousePos.setY(height() - mousePos.y() - 50);
        mousePos.setX(mousePos.x() - 50);

        double dx = mousePos.x() - center.x();
        double dy = mousePos.y() - center.y(); // Y轴向上为正

        angle = qAtan2(dy, dx); // 使用atan2计算角度

        // 确保角度在0到2π之间
        if (angle < 0) {
            angle += 2 * M_PI;
        }

        update(); // 触发重绘
    }
}

void CircleWidget::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    dragging = false;
}

bool CircleWidget::isNearRadius(const QPointF &pos, double threshold) const
{
    QPointF mousePos = pos;

    // 计算半径线的终点
    QPointF endPoint = QPointF(center.x() + radius * qCos(angle),
                               center.y() + radius * qSin(angle));

    // 计算点到线段的最小距离
    double A = mousePos.x() - center.x();
    double B = mousePos.y() - center.y();
    double C = endPoint.x() - center.x();
    double D = endPoint.y() - center.y();

    double dot = A * C + B * D;
    double len_sq = C * C + D * D;
    double param = (len_sq != 0) ? dot / len_sq : -1;

    double closestX, closestY;

    if (param < 0) {
        closestX = center.x();
        closestY = center.y();
    }
    else if (param > 1) {
        closestX = endPoint.x();
        closestY = endPoint.y();
    }
    else {
        closestX = center.x() + param * C;
        closestY = center.y() + param * D;
    }

    double dx = mousePos.x() - closestX;
    double dy = mousePos.y() - closestY;
    double distance = qSqrt(dx * dx + dy * dy);

    return distance <= threshold;
}
